/**
 * Copyright 2016- the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inmorn.orm.mybatis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.inmorn.context.beans.extend.RegisterAnnotationResolve;
import com.inmorn.context.beans.factory.BeanDefinition;
import com.inmorn.context.beans.factory.PropertyDefinition;
import com.inmorn.core.util.StringUtils;
import com.inmorn.orm.mybatis.annotation.MyBatisMapper;

/**
 * @author Jeff.Li
 * @date 2016年11月9日
 */
public class MapperScannerConfigurer implements RegisterAnnotationResolve{

	protected final Logger LOG = LoggerFactory.getLogger(getClass());
	private boolean addToConfig = true;

	private SqlSessionTemplate sqlSessionTemplate;

	private String sqlSessionFactoryBeanName;

	private String sqlSessionTemplateBeanName;

	public Class<?> annotationClass = MyBatisMapper.class;

	public Class<?> getAnnotationClass() {
		return annotationClass;
	}

	public boolean isAddToConfig() {
		return addToConfig;
	}

	public void setAddToConfig(boolean addToConfig) {
		this.addToConfig = addToConfig;
	}

	public SqlSessionTemplate getSqlSessionTemplate() {
		return sqlSessionTemplate;
	}

	public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
		this.sqlSessionTemplate = sqlSessionTemplate;
	}

	public String getSqlSessionFactoryBeanName() {
		return sqlSessionFactoryBeanName;
	}

	public void setSqlSessionFactoryBeanName(String sqlSessionFactoryBeanName) {
		this.sqlSessionFactoryBeanName = sqlSessionFactoryBeanName;
	}

	public String getSqlSessionTemplateBeanName() {
		return sqlSessionTemplateBeanName;
	}

	public void setSqlSessionTemplateBeanName(String sqlSessionTemplateBeanName) {
		this.sqlSessionTemplateBeanName = sqlSessionTemplateBeanName;
	}

	public void setAnnotationClass(Class<?> annotationClass) {
		this.annotationClass = annotationClass;
	}

	public BeanDefinition process(BeanDefinition beanDefinition) {
		Class<?> clazz = beanDefinition.getBeanClass();
		MyBatisMapper myBatisMapper = clazz.getAnnotation(MyBatisMapper.class);
		
		beanDefinition.getPropertys().put("mapperInterface",
				new PropertyDefinition(null, beanDefinition.getBeanClass().getName(), null));
		beanDefinition.setBeanClass(MapperFactoryBean.class);

		beanDefinition.getPropertys().put("addToConfig",
				new PropertyDefinition(null, Boolean.toString(addToConfig), null));

		boolean explicitFactoryUsed = false;
		
		if(StringUtils.isNotEmpty(myBatisMapper.sqlSessionFactoryBeanName())){
			this.sqlSessionFactoryBeanName = myBatisMapper.sqlSessionFactoryBeanName();
		}
		
		if(StringUtils.isEmpty(this.sqlSessionFactoryBeanName)){
			this.sqlSessionFactoryBeanName = "sqlSessionFactory";
		}
		beanDefinition.getPropertys().put("sqlSessionFactory",
				new PropertyDefinition(null, null, this.sqlSessionFactoryBeanName));

		if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
			if (explicitFactoryUsed) {
				LOG.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
			}
			beanDefinition.getPropertys().put("sqlSessionTemplate",
					new PropertyDefinition(null,null,this.sqlSessionTemplateBeanName));
			explicitFactoryUsed = true;
		}

		if (!explicitFactoryUsed) {
			if (LOG.isDebugEnabled()) {
				LOG.debug("Enabling autowire by type for MapperFactoryBean with name '"
						+ beanDefinition.getBeanName() + "'.");
			}
		}
		return beanDefinition;
	}

}
